package com.company.project.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.company.project.core.Result;
import com.company.project.core.ResultGenerator;
import com.company.project.model.Alipay;
import com.company.project.model.OrderMain;
import com.company.project.model.response.OrderItem;
import com.company.project.service.OrderMainService;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * 支付宝支付接口
 */
@RequestMapping("pay")
@RestController()
public class AliPayController {
    // 应用ID
    private final String APP_ID = "2016102200741413";
    /**
     * 私钥
     */
    private final String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDdjck6CrBAde9q01S/Loei47i7Jeo7MPwsqXyqABiLnFX0s/exGEbT2AE+EcjvGkYyvdcpKAvEVD8GwhfLCScyyN6jBdmoXtx2l2otBFMzoPlNNq7By/UZQ5TwaV23/4nmO/6K+BzGzytllMLdubKNWcKcXKKtCBNAwuHuzFzg6ianLvZDp0+SQ0LBOVZRvw771Nyf9KxN/71AwJ3BRiePvKMZskhY+76L+cE3RjICSJx+LeLXUk1jp1hZ6jeQmvmS4BZKeC7WxQagcy5kOuExYDWqA4i2Buu73cPSgXIMJiNTCR7zJrz9Ul62sP1gUDVxP3e32hC/F5ANMAud6IaPAgMBAAECggEARsy7hFfMER1fAAU+rMWixJP/AZdRLc8ultsmonDbZynzcfpc6fP3FlWNuBcY3gfIbQirjFRmxjuh1HgMAG8RXrJAK1qAPsTpsOAcJvyd1f7YDCuwVu/liEhHfTg+ocEAgVmksyYsk/+6P4D1cMOZ4n/PqAYWWjMda/GbH6Og/qJcs9YzJXoaZn2gH4IQCDx5x4J1IsOeXoeXnJ2CuaiUHjmPZiWhHj+upLuy3RIpZdRqdbyp18/wDr4mGILkpThh+p5pGUDIF4l8/t8DzPt9poXzgrGZZyD1tIE5oSrIWyGdFJ0Z0MFJOeiPP4gho5Im8hkHKM/kBFIx96ncof2UKQKBgQDxdqRf1lkO7fnwCrtHb52VRQ7rVXJpYwdDmZVzmbTZrTOkxAp2CheI00itk1tQLi/DQL5JXdS8NuSEQorwMGAhzZuakX6iuKwrz3F7iSTJpurL8++lwOoLrmECTYtZ7jW8Jz+OhRaasynNOSIM06hHaSAelXQFxnktkJgR1XqVWwKBgQDq5E256ovTFgoYSDuXbhwfDSFkXKCWLv7nMuhue5O6LTnAjC9XiQeS/r3FEciNaXwQgFKACAVfnKEhPSr4zQUhMrN9YHocjGJP+cv97vubl8NKF83xDf7no00hhOhJjOsCgagEaOQkKFN1juxsj+K1AVzzxxya8FQV9+VPp+l13QKBgEDFfppmuUUT+TO27T3gZvkfqTzfku1KLyynCjwUQzsRBwVvwQ6g7mc5pglJufjsKsvJlkG/9cz3PJ1t7C86Cs+Gg/MWjE3CFA08fEiTJVcie2FychqYgS/Y+xTPEE5zY96w+I+Wi9W7sb7nUIb4T++393G8zX6vGtpqKyC9j0B5AoGBAJ8/ybKSYdnqx01PK5eu/0HOFSWF5xnrIsZ8rTi6b515q/3vDOm77XarXt2NAPte2M4XMde7mGkKN/PhFJE57pBjX21RS3ivdLfkE3lF3S/P5IcHPIiBhKBnBpQDF7lF4M8COHdE5efdrze0fnXb10gAdJSSGcKxzVBXkRBANvfBAoGAXuzq+6X7ibLY+njYRcVvFmiQUTkDdgwtnty4TaqesaLpzBnlfQcUXdklEFhre2+y1/tWgxKw+ibs6xsFoMh2bk/KmLsS1qWb957+4gPlBoGMSlLKPMJ4w/OwxjY8XI7nN2XpLAbAmKzYiU79Ba3JFqck9ry0PfK2qtZf5kx9lxs=";
    private final String CHARSET = "UTF-8";
    /**
     * 注意这是支付宝公钥，不是应用公钥
     */
    private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAioEwptXmOLe1jOVKgyA78b2xx5kqsciRS1BX+/ZAXxBeGeUFc1m04IhEzlic32S2831V+1e106yojex/k3kKycNLprSRoS/WyF2eDV1BzA4v9mjq7Ftx/c11bkNYF/kaweuyeP+LMeexPU6kUDe7GocSpV8C1gmfG66XVCHLd7tdmRJ/YGOJFPLsuLSCdaGhg2HolVe6EXr1TRN9wJ6KBd3HdQsuFQIAc8t+D36GcT4QfxVBd+3oiUboh2S8YYaB5lDHkTspgn1DTaGvsSjX/D3lrFOKSUA4bnoE3BdUOmmIeps9YfPGp+d7PzHJkORsDc4yXFmZpqA0KJ/P8z+fDwIDAQAB";
    private final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private final String FORMAT = "JSON";
    private final String SIGN_TYPE = "RSA2";
    private final String NOTIFY_URL = "http://127.0.0.1:8800/1";
    private final String RETURN_URL = "http://127.0.0.1:8800/pay/finish";

    @Autowired
    private OrderMainService orderMainService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 阿里支付
     */
    @RequestMapping("alipay")
    public void alipay(@RequestBody Alipay alipay, HttpServletResponse httpResponse) throws IOException {
        //实例化客户端,填入所需参数
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //在公共参数中设置回跳和通知地址
        request.setReturnUrl(RETURN_URL);
        request.setNotifyUrl(NOTIFY_URL);

        request.setBizContent("{\"out_trade_no\":\"" + alipay.getOut_trade_no() + "\","
                + "\"total_amount\":\"" + alipay.getTotal_amount() + "\","
                + "\"subject\":\"" + alipay.getSubject() + "\","
                + "\"body\":\"" + alipay.getBody() + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }


    @RequestMapping(value = "/finish", method = RequestMethod.GET)
    public String returnUrl(HttpServletRequest request, HttpServletResponse response)
            throws IOException, AlipayApiException {
        // 获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("utf-8"), "utf-8");
            params.put(name, valueStr);
        }
        //查看参数都有哪些
        System.out.println(params);
        // 调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
        //验证签名通过
        if (signVerified) {
            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("商户订单号=" + out_trade_no);
            System.out.println("支付宝交易号=" + trade_no);
            System.out.println("付款金额=" + total_amount);

            //支付成功，修复支付状态
            orderMainService.finish(Integer.valueOf(out_trade_no));
            redisTemplate.opsForValue().set(out_trade_no, "success");
            //跳转付款成功页面
            String content = "<html><head><title>支付成功</title></head><body><h1 id=\"h1\"></h1><script type=\"text/javascript\">var i = 3;function CountDown() {var h1 = document.getElementById(\"h1\");h1.innerHTML = \"支付成功！请您到订单页查看，\" + i + \"s后关闭本窗口\";i--;if (i == -1) {setTimeout(function () {window.opener = null;window.open('', '_self');window.close();}, 500);}}timer = setInterval(\"CountDown()\", 1000); </script></body></html>";
            return content;
        } else {
            //跳转付款失败页面
            String content = "<html><head><title>支付失败</title></head><body><h1 id=\"h1\"></h1><script type=\"text/javascript\">var i = 3;function CountDown() {var h1 = document.getElementById(\"h1\");h1.innerHTML = \"支付失败！请您到订单页查看，\" + i + \"s后关闭本窗口\";i--;if (i == -1) {setTimeout(function () {window.opener = null;window.open('', '_self');window.close();}, 500);}}timer = setInterval(\"CountDown()\", 1000); </script></body></html>";
            return content;
        }
    }

    @PostMapping("/success/{id}")
    public Result paySuccess(@RequestBody List<OrderItem> orderList, @PathVariable("id") String userId) {
        if(orderList == null && orderList.size() == 0) {
            return ResultGenerator.genFailResult("参数错误");
        }
        for(OrderItem order : orderList) {
            if(!redisTemplate.hasKey(order.getOrderId().toString())) {
                continue;
            }
            String pay = (String) redisTemplate.opsForValue().get(order.getOrderId().toString());
            if(StringUtils.isEmpty(pay)) {
                continue;
            }
            if("success".equals(pay)) {
                OrderMain orderMain = orderMainService.findBy("orderId", order.getOrderId());
                redisTemplate.opsForValue().set(orderMain.getShopId().toString(), "pay");
                redisTemplate.delete(order.getOrderId().toString());
                redisTemplate.delete(userId);
                return ResultGenerator.genSuccessResult();
            }
        }
        return ResultGenerator.genFailResult("未支付");
    }
}
